{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"http://hilpisch.com/tpq_logo.png\" alt=\"The Python Quants\" width=\"35%\" align=\"right\" border=\"0\"><br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Python for Finance"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Analyze Big Financial Data**\n",
    "\n",
    "O'Reilly (2014)\n",
    "\n",
    "Yves Hilpisch"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img style=\"border:0px solid grey;\" src=\"http://hilpisch.com/python_for_finance.png\" alt=\"Python for Finance\" width=\"30%\" align=\"left\" border=\"0\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Buy the book ** |\n",
    "<a href='http://shop.oreilly.com/product/0636920032441.do' target='_blank'>O'Reilly</a> |\n",
    "<a href='http://www.amazon.com/Yves-Hilpisch/e/B00JCYHHJM' target='_blank'>Amazon</a>\n",
    "\n",
    "**All book codes & IPYNBs** |\n",
    "<a href=\"http://oreilly.quant-platform.com\">http://oreilly.quant-platform.com</a>\n",
    "\n",
    "**The Python Quants GmbH** | <a href='http://pythonquants.com' target='_blank'>www.pythonquants.com</a>\n",
    "\n",
    "**Contact us** | <a href='mailto:analytics@pythonquants.com'>analytics@pythonquants.com</a>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Web Integration"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Web Basics"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### ftplib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false,
    "uuid": "ed06650f-c346-4211-a504-918431567c00"
   },
   "outputs": [],
   "source": [
    "import ftplib\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false,
    "uuid": "f9533953-66c8-428e-8476-fb9b5320cbc3"
   },
   "outputs": [],
   "source": [
    "ftp = ftplib.FTP('quant-platform.com')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false,
    "uuid": "72343084-5e71-42bc-9649-acedaf9bf9b9"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'230 Login successful.'"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ftp.login(user='python', passwd='python')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false,
    "uuid": "bb8b9a5f-2482-4c21-bb52-c5f0c659121b"
   },
   "outputs": [],
   "source": [
    "np.save('./data/array', np.random.standard_normal((100, 100)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false,
    "uuid": "1e23d513-1cbc-4dff-87c8-35bbefd552ea"
   },
   "outputs": [],
   "source": [
    "f = open('./data/array.npy', 'r')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false,
    "uuid": "d7723e2d-8a38-4e76-b18d-47e804bbb9e5"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'226 Transfer complete.'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ftp.storbinary('STOR array.npy', f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false,
    "uuid": "2827d953-cfad-44d3-a2bf-67cf5863a1f7"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-rw-------    1 1001     1001        80080 Aug 08 05:57 array.npy\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'226 Directory send OK.'"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ftp.retrlines('LIST')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false,
    "uuid": "90b28799-36f2-4591-8767-d01b85322596"
   },
   "outputs": [],
   "source": [
    "f = open('./data/array_ftp.npy', 'wb').write"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false,
    "uuid": "bda461e0-6d17-4011-8d12-cae2658b0938"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'226 Transfer complete.'"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ftp.retrbinary('RETR array.npy', f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false,
    "uuid": "fd643a77-53a7-4b88-80a1-992d37141e1b"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'250 Delete operation successful.'"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ftp.delete('array.npy')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false,
    "uuid": "b248ab34-3f84-434b-a4cf-75d3bef1f8fe"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'226 Directory send OK.'"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ftp.retrlines('LIST')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false,
    "uuid": "372f7d6f-928a-436c-bf64-13b0aa994620"
   },
   "outputs": [],
   "source": [
    "ftp.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false,
    "uuid": "a1d9022c-bd30-43e1-b3c7-95bfefe6f60e"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "total 164\r\n",
      "-rw-r--r-- 1 1141 8 77824 Aug  8 12:07 array_ftp.npy\r\n",
      "-rw-r--r-- 1 1141 8 80080 Aug  8 12:07 array.npy\r\n"
     ]
    }
   ],
   "source": [
    "!ls -n ./data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false,
    "uuid": "ed6eb7c9-0004-42a7-b0b3-0e1aa5f27ae1"
   },
   "outputs": [],
   "source": [
    "!rm -f ./data/arr*\n",
    "  # clean-up directory"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false,
    "uuid": "f51de772-ad07-4983-8914-d60383fc0393"
   },
   "outputs": [],
   "source": [
    "ftps = ftplib.FTP_TLS('quant-platform.com')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false,
    "uuid": "442158b0-2c8a-47f5-a60d-3019c687b196"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'230 Login successful.'"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ftps.login(user='python', passwd='python')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false,
    "uuid": "a8ab8f48-5524-423c-936f-b045ac5dc3b0"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'200 PROT now Private.'"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ftps.prot_p()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": false,
    "uuid": "80d163ef-151d-4536-8e16-7fc0774db409"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'226 Directory send OK.'"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ftps.retrlines('LIST')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": false,
    "uuid": "6cb73378-f642-4627-89a9-f6f69f076d9a"
   },
   "outputs": [],
   "source": [
    "ftps.close()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### httplib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": false,
    "uuid": "0d79f4d1-5d93-4c9d-9d62-40dc4981a457"
   },
   "outputs": [],
   "source": [
    "import httplib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": false,
    "uuid": "d665bdf3-fc62-46c0-8f7f-ff125f12ca51"
   },
   "outputs": [],
   "source": [
    "http = httplib.HTTPConnection('hilpisch.com')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false,
    "uuid": "9285e3ee-2035-4816-897f-4c9e2c7c8ef0"
   },
   "outputs": [],
   "source": [
    "http.request('GET', '/index.htm')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": false,
    "uuid": "18a7deaf-ba30-440f-88e7-fd6c90245661"
   },
   "outputs": [],
   "source": [
    "resp = http.getresponse()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false,
    "uuid": "ca638e56-6667-4eea-af63-c2be54c86b9c"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(200, 'OK')"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "resp.status, resp.reason"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": false,
    "uuid": "ea7a144c-81bc-4cab-9132-c70af19773d3"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'<!doctype html>\\n<html lang=\"en\">\\n\\n\\t<head>\\n\\t\\t<meta charset=\"utf-8\">\\n\\n\\t\\t<title>Dr. Yves J. Hilpisch \\xe2\\x80'"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "content = resp.read()\n",
    "content[:100]\n",
    "  # first 100 characters of the file"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": false,
    "uuid": "f8ca3902-3e86-4398-8aa7-e301a0706871"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2070"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "index = content.find(' E ')\n",
    "index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": false,
    "uuid": "4cbca133-e69f-4f1f-8378-de0a212a6fdd"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "' E contact [at] dyjh [dot] de'"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "content[index:index + 29]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": false,
    "uuid": "e1d9bb7e-2429-4a3b-8ad2-ce8e20f398d1"
   },
   "outputs": [],
   "source": [
    "http.close()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### urllib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "collapsed": false,
    "uuid": "7a44c652-b62f-4974-b7be-c1c708c432d2"
   },
   "outputs": [],
   "source": [
    "import urllib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "collapsed": false,
    "uuid": "eeeecf85-e182-44d1-96ca-dfa7c7b770e0"
   },
   "outputs": [],
   "source": [
    "url = 'http://ichart.finance.yahoo.com/table.csv?g=d&ignore=.csv'\n",
    "url += '&s=YHOO&a=01&b=1&c=2014&d=02&e=6&f=2014'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "collapsed": false,
    "uuid": "d0222eb9-e696-477e-9647-adf7296153ac"
   },
   "outputs": [],
   "source": [
    "connect = urllib.urlopen(url)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "collapsed": false,
    "uuid": "afb60cb7-6822-438a-81fd-43cdaca9290c"
   },
   "outputs": [],
   "source": [
    "data = connect.read()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "collapsed": false,
    "uuid": "b97fa159-af2c-4d4c-bd07-3b26e4942f86"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Date,Open,High,Low,Close,Volume,Adj Close\n",
      "2014-03-06,39.599998,39.98,39.50,39.66,10626700,39.66\n",
      "2014-03-05,39.830002,40.150002,39.189999,39.50,12536800,39.50\n",
      "2014-03-04,38.759998,39.790001,38.68,39.630001,16139400,39.630001\n",
      "2014-03-03,37.650002,38.66,37.43,38.25,14714700,38.25\n",
      "2014-02-28,38.549999,39.380001,38.220001,38.669998,16957100,38.669998\n",
      "2014-02-27,37.799999,38.48,37.740002,38.470001,15489400,38.470001\n",
      "2014-02-26,37.349998,38.099998,37.34,37.619999,15778900,37.619999\n",
      "2014-02-25,37.48,37.580002,37.02,37.259998,9756900,37.259998\n",
      "2014-02-24,37.23,37.709999,36.82,37.419998,15738900,37.419998\n",
      "2014-02-21,37.900002,37.959999,37.220001,37.290001,12351900,37.290001\n",
      "2014-02-20,37.830002,38.040001,37.299999,37.790001,11155900,37.790001\n",
      "2014-02-19,38.060001,38.330002,37.68,37.810001,15851900,37.810001\n",
      "2014-02-18,38.310001,38.59,38.09,38.310001,12096400,38.310001\n",
      "2014-02-14,38.43,38.450001,38.110001,38.23,9975800,38.23\n",
      "2014-02-13,37.919998,38.689999,37.790001,38.52,12088100,38.52\n",
      "2014-02-12,38.599998,38.91,38.029999,38.110001,14088500,38.110001\n",
      "2014-02-11,38.150002,38.860001,38.09,38.50,18348000,38.50\n",
      "2014-02-10,38.00,38.130001,37.25,37.759998,17642900,37.759998\n",
      "2014-02-07,36.650002,37.27,36.240002,37.23,16178500,37.23\n",
      "2014-02-06,35.650002,36.75,35.610001,36.240002,14250000,36.240002\n",
      "2014-02-05,35.599998,35.939999,34.990002,35.490002,14022900,35.490002\n",
      "2014-02-04,35.110001,35.860001,34.860001,35.66,21082500,35.66\n",
      "2014-02-03,35.939999,36.009998,34.66,34.900002,22195200,34.900002\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "collapsed": false,
    "uuid": "18dc3eb4-eda6-42f2-b1f8-01454b6303f1"
   },
   "outputs": [],
   "source": [
    "url = 'http://ichart.finance.yahoo.com/table.csv?g=d&ignore=.csv'\n",
    "url += '&%s'  # for replacement with parameters\n",
    "url += '&d=06&e=30&f=2014'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": false,
    "uuid": "92201ad4-66a0-4c39-b0e0-2ac94182dcc2"
   },
   "outputs": [],
   "source": [
    "params = urllib.urlencode({'s': 'MSFT', 'a': '05', 'b': 1, 'c': 2014})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "collapsed": false,
    "uuid": "fe19bda7-77d7-40a8-8b6a-a6fbadf29223"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'a=05&s=MSFT&b=1&c=2014'"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "params"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "collapsed": false,
    "uuid": "3013909d-ce21-4d68-a679-f2fd91f5e104"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'http://ichart.finance.yahoo.com/table.csv?g=d&ignore=.csv&a=05&s=MSFT&b=1&c=2014&d=06&e=30&f=2014'"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "url % params"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "collapsed": false,
    "uuid": "a291f6f5-cc24-47c1-a07b-d7cf5ffbfaf1"
   },
   "outputs": [],
   "source": [
    "connect = urllib.urlopen(url % params)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "collapsed": false,
    "uuid": "fb09a069-94f6-4175-9515-7f2758b367af"
   },
   "outputs": [],
   "source": [
    "data = connect.read()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "collapsed": false,
    "uuid": "5d288e85-ba12-4c37-adbc-42fd8d00b7d3"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Date,Open,High,Low,Close,Volume,Adj Close\n",
      "2014-07-30,44.07,44.099998,43.290001,43.580002,31921400,42.457994\n",
      "2014-07-29,43.91,44.09,43.639999,43.889999,27763100,42.760011\n",
      "2014-07-28,44.360001,44.509998,43.93,43.970001,29684200,42.837953\n",
      "2014-07-25,44.299999,44.66,44.299999,44.50,26737700,43.354306\n",
      "2014-07-24,44.93,45.00,44.32,44.400002,30725300,43.256882\n",
      "2014-07-23,45.450001,45.450001,44.619999,44.869999,52362900,43.714779\n",
      "2014-07-22,45.00,45.150002,44.59,44.830002,43095800,43.675812\n",
      "2014-07-21,44.560001,45.16,44.220001,44.84,37604400,43.685553\n",
      "2014-07-18,44.650002,44.84,44.25,44.689999,43407500,43.539413\n",
      "2014-07-17,45.450001,45.709999,44.25,44.529999,82180300,43.383533\n",
      "2014-07-16,42.509998,44.310001,42.48,44.080002,63318000,42.945121\n",
      "2014-07-15,42.330002,42.470001,42.029999,42.450001,28748700,41.357086\n",
      "2014-07-14,42.220001,42.450001,42.040001,42.139999,21881100,41.055066\n",
      "2014-07-11,41.700001,42.09,41.48,42.09,24083000,41.006354\n",
      "2014-07-10,41.369999,42.00,41.049999,41.689999,21854700,40.616651\n",
      "2014-07-09,41.98,41.990002,41.529999,41.669998,18445900,40.597165\n",
      "2014-07-08,41.869999,42.00,41.610001,41.779999,31218200,40.704334\n",
      "2014-07-07,41.75,42.119999,41.709999,41.990002,21952400,40.90893\n",
      "2014-07-03,41.91,41.990002,41.560001,41.799999,15969300,40.723819\n",
      "2014-07-02,41.73,41.900002,41.529999,41.900002,20208100,40.821247\n",
      "2014-07-01,41.860001,42.150002,41.689999,41.869999,26917000,40.792017\n",
      "2014-06-30,42.169998,42.209999,41.700001,41.700001,30805500,40.626396\n",
      "2014-06-27,41.610001,42.290001,41.509998,42.25,74640000,41.162235\n",
      "2014-06-26,41.93,41.939999,41.43,41.720001,23604400,40.645881\n",
      "2014-06-25,41.700001,42.049999,41.459999,42.029999,20049100,40.947897\n",
      "2014-06-24,41.830002,41.939999,41.560001,41.75,26509100,40.675107\n",
      "2014-06-23,41.73,42.00,41.689999,41.990002,18743900,40.90893\n",
      "2014-06-20,41.450001,41.830002,41.380001,41.68,47764900,40.60691\n",
      "2014-06-19,41.57,41.77,41.330002,41.509998,19828200,40.441285\n",
      "2014-06-18,41.610001,41.740002,41.18,41.650002,27097000,40.577684\n",
      "2014-06-17,41.290001,41.91,40.34,41.68,22518600,40.60691\n",
      "2014-06-16,41.040001,41.610001,41.040001,41.50,24205300,40.431544\n",
      "2014-06-13,41.099998,41.57,40.860001,41.23,26310000,40.168495\n",
      "2014-06-12,40.810001,40.880001,40.290001,40.580002,29818900,39.535232\n",
      "2014-06-11,40.93,41.07,40.77,40.860001,18040000,39.808022\n",
      "2014-06-10,41.029999,41.16,40.860001,41.110001,15117700,40.051585\n",
      "2014-06-09,41.389999,41.48,41.02,41.27,15019200,40.207466\n",
      "2014-06-06,41.48,41.66,41.240002,41.48,24060500,40.412058\n",
      "2014-06-05,40.59,41.25,40.400002,41.209999,31865200,40.149009\n",
      "2014-06-04,40.209999,40.369999,39.860001,40.32,23209000,39.281924\n",
      "2014-06-03,40.599998,40.68,40.25,40.290001,18068900,39.252697\n",
      "2014-06-02,40.950001,41.09,40.68,40.790001,18504300,39.739824\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "collapsed": false,
    "uuid": "60b60a3a-2cce-4f97-aaa7-c042f2e60279"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('./data/msft.csv', <httplib.HTTPMessage instance at 0x7f6568555ab8>)"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "urllib.urlretrieve(url % params, './data/msft.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "collapsed": false,
    "uuid": "acf4d984-2ff8-4258-9a6c-87a86ee2f116"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Date,Open,High,Low,Close,Volume,Adj Close\\n',\n",
       " '2014-07-30,44.07,44.099998,43.290001,43.580002,31921400,42.457994\\n',\n",
       " '2014-07-29,43.91,44.09,43.639999,43.889999,27763100,42.760011\\n',\n",
       " '2014-07-28,44.360001,44.509998,43.93,43.970001,29684200,42.837953\\n',\n",
       " '2014-07-25,44.299999,44.66,44.299999,44.50,26737700,43.354306\\n']"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "csv = open('./data/msft.csv', 'r')\n",
    "csv.readlines()[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "collapsed": false,
    "uuid": "62d5e85b-1590-450c-9018-746e6872f1fa"
   },
   "outputs": [],
   "source": [
    "!rm -f ./data/*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Web Plotting"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Static Plots"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "collapsed": false,
    "uuid": "bb617800-1dc9-4cb9-a7b7-2b8cd16cf0b2"
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "collapsed": false,
    "uuid": "8e1e8943-d88d-4b61-bf19-15e55bebfb3a"
   },
   "outputs": [],
   "source": [
    "url = 'http://ichart.yahoo.com/table.csv?s=MSFT&a=0&b=1&c=2009'\n",
    "data = pd.read_csv(url, parse_dates=['Date'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "collapsed": false,
    "uuid": "ca6562c0-9932-4d5c-9811-4512e717fac3"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7f6556e57190>"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f6556e49bd0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "fig, ax = plt.subplots()\n",
    "data.plot(x='Date', y='Close', grid=True, ax=ax)\n",
    "# tag: microsoft\n",
    "# title: Historical stock prices for Microsoft since January 2009 (+matplotlib+)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Interactive Plots"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**REMARK**: The original version used Bokeh for Web plotting. Plotly seems to be the more easy and intuitive way for generating interactive D3.js Web plots."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "collapsed": false,
    "uuid": "be442f01-3953-4343-b58e-b192628af852"
   },
   "outputs": [],
   "source": [
    "import plotly.plotly as py\n",
    "import cufflinks as cf\n",
    "py.sign_in('Python-Demo-Account', 'gwt101uhh0')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "collapsed": false,
    "uuid": "a83653f0-d602-4bdb-b2ae-6379c50e6f1c"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/anaconda/lib/python2.7/site-packages/plotly/matplotlylib/renderer.py:382: UserWarning:\n",
      "\n",
      "Bummer! Plotly can currently only draw Line2D objects from matplotlib that are in 'data' coordinates!\n",
      "\n",
      "/anaconda/lib/python2.7/site-packages/plotly/matplotlylib/renderer.py:479: UserWarning:\n",
      "\n",
      "I found a path object that I don't think is part of a bar chart. Ignoring.\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<iframe id=\"igraph\" scrolling=\"no\" style=\"border:none;\"seamless=\"seamless\" src=\"https://plot.ly/~Python-Demo-Account/3239.embed\" height=\"525\" width=\"100%\"></iframe>"
      ],
      "text/plain": [
       "<plotly.tools.PlotlyDisplay object>"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# transforming the above mpl figure\n",
    "# to interactive D3.js plot\n",
    "py.iplot_mpl(fig)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<iframe id=\"igraph\" scrolling=\"no\" style=\"border:none;\"seamless=\"seamless\" src=\"https://plot.ly/~Python-Demo-Account/1511.embed\" height=\"525\" width=\"100%\"></iframe>"
      ],
      "text/plain": [
       "<plotly.tools.PlotlyDisplay object>"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# direct approach with Cufflinks\n",
    "data.set_index('Date')['Close'].iplot(world_readable=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Real-Time Plots"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Real-Time FX Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "collapsed": false,
    "uuid": "9adef26f-fc9c-42f2-b203-1387c6ff0b35"
   },
   "outputs": [],
   "source": [
    "import time\n",
    "import pandas as pd\n",
    "import datetime as dt\n",
    "import requests"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "collapsed": false,
    "uuid": "f8cd1e89-f329-411e-9589-79f56fae6d90"
   },
   "outputs": [],
   "source": [
    "url = 'http://api-sandbox.oanda.com/v1/prices?instruments=%s'\n",
    "  # real-time FX (dummy!) data from JSON API"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "collapsed": false,
    "uuid": "592c5d7c-45be-4bfd-92a1-4b0f1a80c551"
   },
   "outputs": [],
   "source": [
    "instrument = 'EUR_USD'\n",
    "api = requests.get(url % instrument)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "collapsed": false,
    "uuid": "00638626-fea7-4e21-9f9f-0b9313000f19"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{u'prices': [{u'ask': 1.24073,\n",
       "   u'bid': 1.24059,\n",
       "   u'instrument': u'EUR_USD',\n",
       "   u'time': u'2015-08-08T09:57:19.523848Z'}]}"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data = api.json()\n",
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "collapsed": false,
    "uuid": "7c95e256-1a25-4ad0-972b-b66d05a2a6ca"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{u'ask': 1.24073,\n",
       " u'bid': 1.24059,\n",
       " u'instrument': u'EUR_USD',\n",
       " u'time': u'2015-08-08T09:57:19.523848Z'}"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data = data['prices'][0]\n",
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "collapsed": false,
    "uuid": "9d23fa5e-b572-4182-aca2-46f8db6f5615"
   },
   "outputs": [],
   "source": [
    "ticks = pd.DataFrame({'bid': data['bid'],\n",
    "                      'ask': data['ask'],\n",
    "                      'instrument': data['instrument'],\n",
    "                      'time': pd.Timestamp(data['time'])},\n",
    "                      index=[pd.Timestamp(data['time']),])\n",
    "  # initialization of ticks DataFrame"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {
    "collapsed": false,
    "uuid": "012c3b07-bbab-4484-931f-68daef241186"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ask</th>\n",
       "      <th>bid</th>\n",
       "      <th>instrument</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2015-08-08 09:57:19.523848+00:00</th>\n",
       "      <td>1.24073</td>\n",
       "      <td>1.24059</td>\n",
       "      <td>EUR_USD</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                      ask      bid instrument\n",
       "2015-08-08 09:57:19.523848+00:00  1.24073  1.24059    EUR_USD"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ticks[['ask', 'bid', 'instrument']]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Real-Time Stock Price Quotes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {
    "collapsed": false,
    "uuid": "33bbf187-b9ea-4a56-8132-a5ba5fcfd310"
   },
   "outputs": [],
   "source": [
    "url1 = 'http://www.netfonds.no/quotes/posdump.php?'\n",
    "url2 = 'date=%s%s%s&paper=%s.N&csv_format=csv'\n",
    "url = url1 + url2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {
    "collapsed": false,
    "uuid": "976c17f6-bc3f-4238-a121-5c8c483b685d"
   },
   "outputs": [],
   "source": [
    "# must be a business day\n",
    "today = dt.datetime.now()\n",
    "y = '%d' % today.year\n",
    "  # current year\n",
    "m = '%02d' % today.month\n",
    "  # current month, add leading zero if needed\n",
    "d = '%02d' % today.day\n",
    "  # current day, add leading zero if needed\n",
    "sym = 'NKE'\n",
    "  # Nike Inc. stocks"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "collapsed": false,
    "uuid": "51351a83-4e9d-427a-ac87-183a59d1ae19"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('2015', '08', '08', 'NKE')"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y, m, d, sym"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {
    "collapsed": false,
    "uuid": "3e2596c2-2ea2-419c-9c0f-a525eef874d5"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'http://www.netfonds.no/quotes/posdump.php?date=20150808&paper=NKE.N&csv_format=csv'"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "urlreq = url % (y, m, d, sym)\n",
    "urlreq"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "collapsed": false,
    "uuid": "cd2c7a3b-9a59-4a62-994e-4470cfec9011"
   },
   "outputs": [],
   "source": [
    "data = pd.read_csv(urlreq, parse_dates=['time'])\n",
    "  # initialize DataFrame object"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Index: 0 entries\n",
      "Data columns (total 7 columns):\n",
      "time                 0 non-null object\n",
      "bid                  0 non-null object\n",
      "bid_depth            0 non-null object\n",
      "bid_depth_total      0 non-null object\n",
      "offer                0 non-null object\n",
      "offer_depth          0 non-null object\n",
      "offer_depth_total    0 non-null object\n",
      "dtypes: object(7)\n",
      "memory usage: 0.0+ bytes\n"
     ]
    }
   ],
   "source": [
    "data.info()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Rapid Web Applications"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Traders' Chat Room"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Data Modeling"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The Python Code"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Imports and Database Preliminaries"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Core Functionality"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Templating"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {
    "collapsed": false,
    "uuid": "1463132b-34c8-4238-8d3e-6ba5c7562194"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'1, 2, 3'"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'%d, %d, %d' % (1, 2, 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {
    "collapsed": false,
    "uuid": "c5c11d6d-ad65-4ee7-9ebe-91dc1c3d2497"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'1, 2, 3'"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'{}, {}, {}'.format(1, 2, 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {
    "collapsed": false,
    "uuid": "7ff70268-2c8f-45a5-a6b0-17bb9d77cc14"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'1, 2, 3'"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'{}, {}, {}'.format(*'123')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {
    "collapsed": false,
    "uuid": "da70e7f6-9068-4039-bdfc-8bfe510a7ee6"
   },
   "outputs": [],
   "source": [
    "templ = '''<!doctype html>\n",
    "  Just print out <b>numbers</b> provided to the template.\n",
    "  <br><br>\n",
    "  {% for number in numbers %}\n",
    "    {{ number }}\n",
    "  {% endfor %}\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {
    "collapsed": false,
    "uuid": "6b66b22b-fb7f-4dc7-99f4-ed6550e9eb2f"
   },
   "outputs": [],
   "source": [
    "from jinja2 import Template"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {
    "collapsed": false,
    "uuid": "641a5ee8-9ef7-4e60-80cb-c73b1d81f182"
   },
   "outputs": [],
   "source": [
    "t = Template(templ)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {
    "collapsed": false,
    "uuid": "ad91b975-9917-4d22-99db-635d745308a8"
   },
   "outputs": [],
   "source": [
    "html = t.render(numbers=range(5))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {
    "collapsed": false,
    "uuid": "3ddf0465-00f2-4c70-8547-7460eba6f11d"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "u'<!doctype html>\\n  Just print out <b>numbers</b> provided to the template.\\n  <br><br>\\n  \\n    0\\n  \\n    1\\n  \\n    2\\n  \\n    3\\n  \\n    4\\n  '"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "html"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {
    "collapsed": false,
    "uuid": "d8d44498-a17f-41b3-9e91-6d09a288c5b8"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<!doctype html>\n",
       "  Just print out <b>numbers</b> provided to the template.\n",
       "  <br><br>\n",
       "  \n",
       "    0\n",
       "  \n",
       "    1\n",
       "  \n",
       "    2\n",
       "  \n",
       "    3\n",
       "  \n",
       "    4\n",
       "  "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from IPython.display import HTML\n",
    "HTML(html)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Styling"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {
    "collapsed": false,
    "uuid": "41649870-1061-444f-924c-733ecdef2ebb"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "../python/tradechat\n",
      "tradechat.db\n",
      "tables.sql\n",
      "tradechat.py\n",
      "../python/tradechat/templates\n",
      "show_entries.html\n",
      "layout.html\n",
      "register.html\n",
      "login.html\n",
      "../python/tradechat/static\n",
      "style.css\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "for path, dirs, files in os.walk('../python/tradechat'):\n",
    "  print path\n",
    "  for f in files:\n",
    "    print f"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Web Services"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The Financial Model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The Implementation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {
    "collapsed": false,
    "uuid": "79f9048b-3427-4a79-9cbc-4bf414c0730c"
   },
   "outputs": [],
   "source": [
    "import sys\n",
    "sys.path.append(\"../python/volservice\")\n",
    "  # adjust if necessary to your path"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {
    "collapsed": false,
    "uuid": "baba8c94-1d56-42aa-a491-da6b7a9f649f"
   },
   "outputs": [],
   "source": [
    "from werkzeug.wrappers import Request, Response "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {
    "collapsed": false,
    "uuid": "5cbccdda-a5a3-4c7e-97ac-3df9b05c5efb"
   },
   "outputs": [],
   "source": [
    "from vol_pricing_service import get_option_value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {
    "collapsed": false,
    "uuid": "b6bad926-3093-4f80-aedd-aef6e7950749"
   },
   "outputs": [],
   "source": [
    "def application(environ, start_response):\n",
    "    request = Request(environ)\n",
    "      # wrap environ in new object\n",
    "    text = get_option_value(request.args)\n",
    "      # provide all paramters of the call to function\n",
    "      # get back either error message or option value\n",
    "    response = Response(text, mimetype='text/html')\n",
    "      # generate response object based on the returned text\n",
    "    return response(environ, start_response)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {
    "collapsed": false,
    "uuid": "a5708e66-1b39-4f82-b07f-44cb07c68280"
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import urllib\n",
    "url = 'http://localhost:4000/'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Conclusions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Further Reading"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"http://hilpisch.com/tpq_logo.png\" alt=\"The Python Quants\" width=\"35%\" align=\"right\" border=\"0\"><br>\n",
    "\n",
    "<a href=\"http://www.pythonquants.com\" target=\"_blank\">www.pythonquants.com</a> | <a href=\"http://twitter.com/dyjh\" target=\"_blank\">@dyjh</a>\n",
    "\n",
    "<a href=\"mailto:analytics@pythonquants.com\">analytics@pythonquants.com</a>\n",
    "\n",
    "**Python Quant Platform** |\n",
    "<a href=\"http://oreilly.quant-platform.com\">http://oreilly.quant-platform.com</a>\n",
    "\n",
    "**Derivatives Analytics with Python** |\n",
    "<a href=\"http://www.derivatives-analytics-with-python.com\" target=\"_blank\">Derivatives Analytics @ Wiley Finance</a>\n",
    "\n",
    "**Python for Finance** |\n",
    "<a href=\"http://shop.oreilly.com/product/0636920032441.do\" target=\"_blank\">Python for Finance @ O'Reilly</a>"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python2",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
